﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Security;
using Apodidae.Common;
using Apodidae.Core.Dao;
using Apodidae.Domain.Entity;
using ComDevFx.Arch.Base.Persister;

namespace Apodidae.Core.Imp
{
    public class UserService : ServiceBase, IUserService
    {
        private UserInfoDao _userInfoDao;
        private  const string INNERENCRYPTPRIVATEKEY = "~@#$%^&*()-+zxcvbqwe123;><";

        protected override void PrepareInternal()
        {
            _userInfoDao = new UserInfoDao();
        }


        #region 获取用户对象信息相关操作

        /// <summary>
        /// 根据用户ID获取用户信息对象
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <returns></returns>
        public UserInfo GetUserByUserId(string userId)
        {
            return _userInfoDao.Get(userId);
        }

        /// <summary>
        /// 根据用户名获取用户对象
        /// </summary>
        /// <param name="loginId">用户名</param>
        /// <returns></returns>
        public UserInfo GetUserByLoginId(string loginId)
        {
            return _userInfoDao.Query(string.Format("where this.LoginId='{0}'", loginId)).First();
        }

        #endregion

        #region 登陆相关操作

        /// <summary>
        /// 用户登陆
        /// </summary>
        /// <param name="loginName">用户名</param>
        /// <param name="cookieDomain">站点所在的域</param>
        public void SetUserAuthIn(string loginName, string cookieDomain)
        {
            #region MyRegion
            //string idenNames = String.Format("{0}\n{1}\n{2}\n{3}\n{4}\n{5}\n{6}",
            //    "0", // is not operator
            //    user.StringId,
            //    (user.RegSiteId == SiteService.SiteRoot.BaseInternalSiteId ? "1" : "0"),
            //    user.RegSiteId,
            //    user.Email,
            //    user.LoginId,
            //    (user.LastLoginIp != null ? user.LastLoginIp : ""));

            //FormsAuthentication.SetAuthCookie(idenNames, false);
            ////HttpContext.Current.Response.Cookies[FormsAuthentication.FormsCookieName].Domain = cookieDomain;
            //HttpCookie cookie = FormsAuthentication.GetAuthCookie(idenNames, false);
            //cookie.Domain = cookieDomain;
            //HttpContext.Current.Response.SetCookie(cookie);
            #endregion

            UserInfo userInfo = this.GetUserByLoginId(loginName);
            if (userInfo == null)
                throw new Exception("用户不存在");

            string idenNames = string.Format("{0}\n{1}\n{2}",
                                             userInfo.Id,
                                             userInfo.LoginId,
                                             (userInfo.UserType.HasValue ? ((int)userInfo.UserType.Value).ToString(CultureInfo.InvariantCulture) : "0"));

            //更新用户信息
            userInfo.LastLoginDate = DateTime.Now;
 
            //设置用户的 cookie 的值
            FormsAuthentication.SetAuthCookie(idenNames, false);

            _userInfoDao.SaveOrUpdate(userInfo);
               
            ////获取用户的 cookie 
            //HttpCookie cookie = FormsAuthentication.GetAuthCookie(loginName, false);
            //cookie.Domain = cookieDomain;   //所在的站点在部署的时候的域名一定要与指定的域相同，否则是无法登陆的
            //HttpContext.Current.Response.SetCookie(cookie);
        }

        /// <summary>
        /// 用户退出
        /// </summary>
        /// <param name="cookieDomain">站点所在的域</param>
        public void SetAuthOut(string cookieDomain)
        {
            FormsAuthentication.SignOut();

            //HttpCookie cookie = HttpContext.Current.Response.Cookies[FormsAuthentication.FormsCookieName];
            //cookie.Domain = cookieDomain;   //所在的站点在部署的时候的域名一定要与指定的域相同，否则是无法登陆的
            //cookie.Expires = DateTime.Now.AddDays(-1);
            //HttpContext.Current.Response.Cookies.Add(cookie);
        }

        /// <summary>
        /// 获取当前登陆的用户对象
        /// </summary>
        /// <returns></returns>
        public UserInfo GetCurrentPerson()
        {
            string personId = GetCurrentPersonId();
            if (string.IsNullOrEmpty(personId))
                return null;

            UserInfo person = this.GetUserByUserId(personId);
            if (person == null)
                return null;

            return person;
        }

        /// <summary>
        /// 验证登陆
        /// </summary>
        /// <param name="loginId">登陆名</param>
        /// <param name="pwd">密码</param>
        /// <param name="domainName">域名</param>
        /// <returns></returns>
        public AutherResult ValidateLogin(string loginId, string pwd, string domainName)
        {
            UserInfo userinfo = this.GetUserByLoginId(loginId);
            if (userinfo == null)
                return AutherResult.UserNotFind;

            if (!this.ComparePassword(pwd, userinfo.Pwd))
                return AutherResult.ErrPWD;

            if (userinfo.IsSuspend)
                return AutherResult.Suspent;

            return AutherResult.Succeed;
        }

        /// <summary>
        /// 获取当前用户登陆的在cookie中保存的用户信息
        /// </summary>
        /// <returns></returns>
        private string GetCurrentPersonId()
        {
            string idenName = string.Empty;

            if (HttpContext.Current != null && HttpContext.Current.User != null)
            {
                idenName = HttpContext.Current.User.Identity.Name;  //这里的name可以自己组建更丰富的内容

                string[] idenNames = idenName.Split('\n');
                return idenNames[0];
            }

            return idenName;
        }

        #endregion

        #region 用户操作相关


        public void SuspendUser(string userId)
        {
            UserInfo user = GetUserByUserId(userId);
            if (user == null)
                throw new Exception("用户不存在");

            user.IsSuspend = true;
            user.LastSuspentTime = DateTime.Now;

            _userInfoDao.SaveOrUpdate(user);
        }

        public UserInfo CreateUser(string loginId, string pwd, string email, string realName,
            UserType uType)
        {
            var userinfo = new UserInfo
                {
                    LoginId = loginId,
                    Pwd = this.EncryptPasswordContent(pwd),
                    Email = email,
                    RealName = realName,
                    UserType = uType,
                    LastLoginDate = DateTime.Now
                };

            //创建新用户
            _userInfoDao.Save(userinfo);

            return userinfo;
        }

        #endregion

        #region 密码操作相关
        /// <summary>
        /// 加密密码内容
        /// </summary>
        /// <param name="orginalPwd">原始的密码串</param>
        /// <returns></returns>
        private string EncryptPasswordContent(string orginalPwd)
        {
            return Utilies.GetMd5(string.Format("{0}{1}", orginalPwd, INNERENCRYPTPRIVATEKEY));
        }

        /// <summary>
        /// 更改密码
        /// </summary>
        /// <param name="user"></param>
        /// <param name="newPwd"></param>
        public void ChangePassword(UserInfo user, string newPwd)
        {
            user.Pwd = EncryptPasswordContent(newPwd);

            _userInfoDao.SaveOrUpdate(user);
        }

        /// <summary>
        /// 比较密码
        /// </summary>
        /// <param name="orginalPwd">用户的输入的密码内容</param>
        /// <param name="pwdFromDb">从数据库中获取出的加过密的密码内容</param>
        /// <returns>true:正确, false:错误</returns>
        public bool ComparePassword(string orginalPwd, string pwdFromDb)
        {
            orginalPwd = EncryptPasswordContent(orginalPwd);
            return System.String.CompareOrdinal(orginalPwd, pwdFromDb) == 0 ? true : false;
        }
        #endregion

        #region CURD UserInfo

        public UserInfo Save(UserInfo entity)
        {
            return _userInfoDao.Save(entity) as UserInfo;
        }
        public void SaveOrUpdate(UserInfo entity)
        {
            _userInfoDao.SaveOrUpdate(entity);
        }
        public void Delete(UserInfo entity)
        {
            _userInfoDao.Delete(entity);
        }

        #endregion
    }
}
